import { configService, type NetworkSurveyConfig } from './configService'

// 扫描任务数据接口 - 所有IP使用统一的端口范围
export interface ScanTaskData {
  taskName: string
  description?: string
  startIp: string            // 起始IP
  endIp: string              // 终止IP
  startPort: number          // 统一的起始端口
  endPort: number            // 统一的结束端口
  timestamp: string
}


// 扫描响应接口
export interface ScanResponse {
  success: boolean
  message: string
  taskId?: string
  data?: any
}

class NetworkSurveyService {
  private config: NetworkSurveyConfig | null = null

  /**
   * 初始化服务
   */
  async init() {
    this.config = await configService.getNetworkSurveyConfig()
  }

  /**
   * 提交扫描任务
   * @param taskData 扫描任务数据
   * @returns Promise<ScanResponse>
   */
  async submitScanTask(taskData: ScanTaskData): Promise<ScanResponse> {
    if (!this.config) {
      await this.init()
    }

    // 验证扫描数据
    const validation = this.validateScanData(taskData)
    if (!validation.valid) {
      throw new Error(`数据验证失败: ${validation.errors.join(', ')}`)
    }

    const url = this.config!.endpoints.submitScanTask
    
    try {
      console.log('提交扫描任务到:', url)
      console.log('扫描任务数据:', taskData)

      const response = await fetch(url, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          'Accept': 'application/json'
        },
        body: JSON.stringify(taskData),
        signal: this.createTimeoutSignal(this.config!.timeout)
      })

      if (!response.ok) {
        throw new Error(`HTTP error! status: ${response.status}`)
      }

      // 尝试解析JSON响应（后端会返回任务ID）
      let responseData
      try {
        responseData = await response.json()
      } catch (jsonError) {
        // 如果不是JSON，尝试获取文本
        const textResponse = await response.text()
        responseData = { response: textResponse }
      }

      console.log('扫描任务提交成功，后端响应:', responseData)

      // 从后端响应中提取任务ID（字段名暂未确定，尝试常见字段）
      const taskId = responseData?.taskId || responseData?.id || responseData?.task_id || 
                     responseData?.data?.taskId || responseData?.data?.id || 
                     `local_${Date.now()}`  // 如果后端没有返回ID，使用本地生成的临时ID

      return {
        success: true,
        message: '扫描任务提交成功',
        taskId: taskId,
        data: responseData
      }
    } catch (error) {
      console.error('提交扫描任务失败:', error)
      
      // 重试逻辑
      return await this.retrySubmitTask(taskData, 1)
    }
  }

  /**
   * 重试提交扫描任务
   * @param taskData 扫描任务数据
   * @param attempt 当前尝试次数
   * @returns Promise<ScanResponse>
   */
  private async retrySubmitTask(taskData: ScanTaskData, attempt: number): Promise<ScanResponse> {
    if (attempt > this.config!.retryCount) {
      return {
        success: false,
        message: `提交失败，已重试 ${this.config!.retryCount} 次`
      }
    }

    console.log(`重试提交扫描任务，第 ${attempt} 次尝试`)
    
    // 等待一段时间后重试
    await new Promise(resolve => setTimeout(resolve, 1000 * attempt))

    try {
      const url = this.config!.endpoints.submitScanTask
      
      const response = await fetch(url, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          'Accept': 'application/json'
        },
        body: JSON.stringify(taskData),
        signal: this.createTimeoutSignal(this.config!.timeout)
      })

      if (!response.ok) {
        throw new Error(`HTTP error! status: ${response.status}`)
      }

      let responseData
      try {
        responseData = await response.json()
      } catch (jsonError) {
        const textResponse = await response.text()
        responseData = { response: textResponse }
      }

      console.log('重试提交成功，后端响应:', responseData)

      // 从后端响应中提取任务ID
      const taskId = responseData?.taskId || responseData?.id || responseData?.task_id || 
                     responseData?.data?.taskId || responseData?.data?.id || 
                     `local_${Date.now()}`

      return {
        success: true,
        message: `扫描任务提交成功（第 ${attempt} 次重试）`,
        taskId: taskId,
        data: responseData
      }
    } catch (error) {
      console.error(`第 ${attempt} 次重试失败:`, error)
      return await this.retrySubmitTask(taskData, attempt + 1)
    }
  }

  /**
   * 获取扫描状态
   * @param taskId 任务ID
   * @returns Promise<any>
   */
  async getScanStatus(taskId: string): Promise<any> {
    if (!this.config) {
      await this.init()
    }

    const url = `${this.config!.endpoints.getScanStatus}?taskId=${taskId}`

    try {
      const response = await fetch(url, {
        method: 'GET',
        headers: {
          'Accept': 'application/json'
        },
        signal: this.createTimeoutSignal(this.config!.timeout)
      })

      if (!response.ok) {
        throw new Error(`HTTP error! status: ${response.status}`)
      }

      return await response.json()
    } catch (error) {
      console.error('获取扫描状态失败:', error)
      throw error
    }
  }

  /**
   * 获取扫描结果
   * @param taskId 任务ID
   * @returns Promise<any>
   */
  async getScanResults(taskId: string): Promise<any> {
    if (!this.config) {
      await this.init()
    }

    const url = `${this.config!.endpoints.getScanResults}?taskId=${taskId}`

    try {
      const response = await fetch(url, {
        method: 'GET',
        headers: {
          'Accept': 'application/json'
        },
        signal: this.createTimeoutSignal(this.config!.timeout)
      })

      if (!response.ok) {
        throw new Error(`HTTP error! status: ${response.status}`)
      }

      return await response.json()
    } catch (error) {
      console.error('获取扫描结果失败:', error)
      throw error
    }
  }


  /**
   * 获取在线广度扫描任务结果
   * @param taskId 任务ID
   * @returns Promise<any>
   */
  async getCoarseGrainedScanResults(taskId: string): Promise<any> {
    if (!this.config) {
      await this.init()
    }

    // 使用相对路径，让 Vite 代理处理请求
    // 路径已包含任务ID，使用 GET 方法
    const url = `/coarse-grained_scan_tasks/${taskId}/results`

    try {
      // 使用更长的超时时间（30秒），因为获取任务结果可能需要一些时间
      const timeout = 30000
      const response = await fetch(url, {
        method: 'GET',
        headers: {
          'Accept': 'application/json'
        },
        signal: this.createTimeoutSignal(timeout)
      })

      if (!response.ok) {
        throw new Error(`HTTP error! status: ${response.status}`)
      }

      return await response.json()
    } catch (error) {
      console.error('获取在线广度扫描任务结果失败:', error)
      // 如果是超时错误，提供更友好的错误信息
      if (error instanceof Error && error.name === 'AbortError') {
        throw new Error('请求超时，请稍后重试')
      }
      throw error
    }
  }

  /**
   * 获取所有粗粒度扫描任务
   * @returns Promise<any[]>
   */
  async getAllCoarseGrainedTasks(): Promise<any[]> {
    if (!this.config) {
      await this.init()
    }

    // 使用相对路径，让 Vite 代理处理请求
    const url = `/coarse-grained_tasks`

    try {
      // 使用更长的超时时间（60秒），因为获取所有任务可能需要更长时间
      const timeout = 60000
      const response = await fetch(url, {
        method: 'GET',
        headers: {
          'Accept': 'application/json'
        },
        signal: this.createTimeoutSignal(timeout)
      })

      if (!response.ok) {
        throw new Error(`HTTP error! status: ${response.status}`)
      }

      return await response.json()
    } catch (error) {
      console.error('获取所有粗粒度扫描任务失败:', error)
      // 如果是超时错误，提供更友好的错误信息
      if (error instanceof Error && error.name === 'AbortError') {
        throw new Error('请求超时，请稍后重试')
      }
      throw error
    }
  }

    /**
   * 获取广度-深度总任务映射表
   * /api/get_general_tasks
   */
  async getGeneralTasks(): Promise<Array<{
    general_task_id: string
    fine_task_id: string
    coarse_task_id: string
  }>> {
    const url = '/api/get_general_tasks'

    try {
      const timeout = 30000
      const response = await fetch(url, {
        method: 'GET',
        headers: { Accept: 'application/json' },
        signal: this.createTimeoutSignal(timeout)
      })

      if (!response.ok) {
        throw new Error(`HTTP error! status: ${response.status}`)
      }

      return await response.json()
    } catch (error) {
      console.error('获取广度-深度总任务映射失败:', error)
      return []
    }
  }



  /**
   * 将IP地址转换为数字（用于比较）
   * @param ip IP地址
   * @returns 数字
   */
  private ipToNumber(ip: string): number {
    const parts = ip.split('.').map(Number)
    return parts[0] * 256 * 256 * 256 + parts[1] * 256 * 256 + parts[2] * 256 + parts[3]
  }

  /**
   * 创建超时信号
   * @param timeout 超时时间(毫秒)
   * @returns AbortSignal
   */
  private createTimeoutSignal(timeout: number): AbortSignal {
    const controller = new AbortController()
    setTimeout(() => {
      controller.abort()
    }, timeout)
    return controller.signal
  }

  /**
   * 验证扫描数据
   * @param taskData 扫描任务数据
   * @returns 验证结果
   */
  validateScanData(taskData: ScanTaskData): { valid: boolean; errors: string[] } {
    const errors: string[] = []
    
    if (!taskData.taskName || taskData.taskName.trim().length === 0) {
      errors.push('任务名称不能为空')
    }
    
    // 验证IP格式（简单验证）
    const ipRegex = /^(\d{1,3}\.){3}\d{1,3}$/
    
    if (!taskData.startIp || !ipRegex.test(taskData.startIp)) {
      errors.push(`起始IP格式错误: ${taskData.startIp}`)
    }
    
    if (!taskData.endIp || !ipRegex.test(taskData.endIp)) {
      errors.push(`终止IP格式错误: ${taskData.endIp}`)
    }
    
    // 如果两个IP都有效，检查起始IP是否小于等于终止IP
    if (errors.length === 0) {
      const startNum = this.ipToNumber(taskData.startIp)
      const endNum = this.ipToNumber(taskData.endIp)
      
      if (startNum > endNum) {
        errors.push('起始IP不能大于终止IP')
      }
    }
    
    if (!taskData.startPort || taskData.startPort < 1 || taskData.startPort > 65535) {
      errors.push(`起始端口无效: ${taskData.startPort}（应在1-65535之间）`)
    }
    
    if (!taskData.endPort || taskData.endPort < 1 || taskData.endPort > 65535) {
      errors.push(`结束端口无效: ${taskData.endPort}（应在1-65535之间）`)
    }
    
    if (taskData.startPort > taskData.endPort) {
      errors.push('起始端口不能大于结束端口')
    }
    
    return {
      valid: errors.length === 0,
      errors
    }
  }
}

// 导出单例实例
export const networkSurveyService = new NetworkSurveyService()

